home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 February (DVD) / PCWorld_2008-02_DVD.iso / v cisle / PHP / PHP.exe / EasyPHP-2.0b1-setup.exe / {app} / phpmyadmin / libraries / relation.lib.php < prev    next >
Encoding:
PHP Script  |  2006-11-18  |  33.6 KB  |  914 lines

  1. <?php
  2. /* $Id: relation.lib.php 8677 2006-02-24 20:31:45Z lem9 $ */
  3. // vim: expandtab sw=4 ts=4 sts=4:
  4.  
  5. require_once './libraries/Table.class.php';
  6.  
  7. /**
  8.  * Set of functions used with the relation and pdf feature
  9.  */
  10.  
  11. /**
  12.  * Executes a query as controluser if possible, otherwise as normal user
  13.  *
  14.  * @param   string    the query to execute
  15.  * @param   boolean   whether to display SQL error messages or not
  16.  *
  17.  * @return  integer   the result id
  18.  *
  19.  * @global  string    the URL of the page to show in case of error
  20.  * @global  string    the name of db to come back to
  21.  * @global  resource  the resource id of DB connect as controluser
  22.  * @global  array     configuration infos about the relations stuff
  23.  *
  24.  * @access  public
  25.  *
  26.  * @author  Mike Beck <mikebeck@users.sourceforge.net>
  27.  */
  28.  function PMA_query_as_cu($sql, $show_error = true, $options = 0) {
  29.     global $db, $controllink, $cfgRelation;
  30.  
  31.     // Comparing resource ids works on PHP 5 because, when no controluser
  32.     // is defined, connecting with the same user for controllink does
  33.     // not create a new connection. However a new connection is created
  34.     // on PHP 4, so we cannot directly compare resource ids.
  35.  
  36.     if ($controllink == $GLOBALS['userlink'] || PMA_MYSQL_INT_VERSION < 50000) {
  37.         PMA_DBI_select_db($cfgRelation['db'], $controllink);
  38.     }
  39.     if ($show_error) {
  40.         $result = PMA_DBI_query($sql, $controllink, $options);
  41.     } else {
  42.         $result = @PMA_DBI_try_query($sql, $controllink, $options);
  43.     } // end if... else...
  44.     // It makes no sense to restore database on control user
  45.     if ($controllink == $GLOBALS['userlink'] || PMA_MYSQL_INT_VERSION < 50000) {
  46.         PMA_DBI_select_db($db, $controllink);
  47.     }
  48.  
  49.     if ($result) {
  50.         return $result;
  51.     } else {
  52.         return false;
  53.     }
  54.  } // end of the "PMA_query_as_cu()" function
  55.  
  56.  
  57. /**
  58.  * Defines the relation parameters for the current user
  59.  * just a copy of the functions used for relations ;-)
  60.  * but added some stuff to check what will work
  61.  *
  62.  * @param   boolean  whether to check validity of settings or not
  63.  *
  64.  * @return  array    the relation parameters for the current user
  65.  *
  66.  * @global  array    the list of settings for servers
  67.  * @global  integer  the id of the current server
  68.  * @global  string   the URL of the page to show in case of error
  69.  * @global  string   the name of the current db
  70.  * @global  string   the name of the current table
  71.  * @global  array    configuration infos about the relations stuff
  72.  *
  73.  * @access  public
  74.  *
  75.  * @author  Mike Beck <mikebeck@users.sourceforge.net>
  76.  */
  77. function PMA_getRelationsParam($verbose = false)
  78. {
  79.     global $cfg, $server, $controllink, $cfgRelation;
  80.  
  81.     $cfgRelation                = array();
  82.     $cfgRelation['relwork']     = false;
  83.     $cfgRelation['displaywork'] = false;
  84.     $cfgRelation['bookmarkwork']= false;
  85.     $cfgRelation['pdfwork']     = false;
  86.     $cfgRelation['commwork']    = false;
  87.     $cfgRelation['mimework']    = false;
  88.     $cfgRelation['historywork'] = false;
  89.     $cfgRelation['allworks']    = false;
  90.  
  91.     // No server selected -> no bookmark table
  92.     // we return the array with the falses in it,
  93.     // to avoid some 'Unitialized string offset' errors later
  94.     if ($server == 0 || empty($cfg['Server']) || empty($cfg['Server']['pmadb'])
  95.       || ! PMA_DBI_select_db($cfg['Server']['pmadb'], $controllink)) {
  96.         if ($verbose == true) {
  97.             echo 'PMA Database ... '
  98.                  . '<font color="red"><b>' . $GLOBALS['strNotOK'] . '</b></font>'
  99.                  . '[ <a href="Documentation.html#pmadb">' . $GLOBALS['strDocu']
  100.                  . '</a> ]<br />' . "\n"
  101.                  . $GLOBALS['strGeneralRelationFeat']
  102.                  . ' <font color="green">' . $GLOBALS['strDisabled']
  103.                  . '</font>' . "\n";
  104.         }
  105.         $cfg['Server']['pmadb'] = false;
  106.         return $cfgRelation;
  107.     }
  108.  
  109.     $cfgRelation['user']  = $cfg['Server']['user'];
  110.     $cfgRelation['db']    = $cfg['Server']['pmadb'];
  111.  
  112.     //  Now I just check if all tables that i need are present so I can for
  113.     //  example enable relations but not pdf...
  114.     //  I was thinking of checking if they have all required columns but I
  115.     //  fear it might be too slow
  116.  
  117.     $tab_query = 'SHOW TABLES FROM ' . PMA_backquote($cfgRelation['db']);
  118.     $tab_rs    = PMA_query_as_cu($tab_query, false, PMA_DBI_QUERY_STORE);
  119.  
  120.     if ($tab_rs) {
  121.         while ($curr_table = @PMA_DBI_fetch_row($tab_rs)) {
  122.             if ($curr_table[0] == $cfg['Server']['bookmarktable']) {
  123.                 $cfgRelation['bookmark']        = $curr_table[0];
  124.             } elseif ($curr_table[0] == $cfg['Server']['relation']) {
  125.                 $cfgRelation['relation']        = $curr_table[0];
  126.             } elseif ($curr_table[0] == $cfg['Server']['table_info']) {
  127.                 $cfgRelation['table_info']      = $curr_table[0];
  128.             } elseif ($curr_table[0] == $cfg['Server']['table_coords']) {
  129.                 $cfgRelation['table_coords']    = $curr_table[0];
  130.             } elseif ($curr_table[0] == $cfg['Server']['column_info']) {
  131.                 $cfgRelation['column_info'] = $curr_table[0];
  132.             } elseif ($curr_table[0] == $cfg['Server']['pdf_pages']) {
  133.                 $cfgRelation['pdf_pages']       = $curr_table[0];
  134.             } elseif ($curr_table[0] == $cfg['Server']['history']) {
  135.                 $cfgRelation['history'] = $curr_table[0];
  136.             }
  137.         } // end while
  138.         PMA_DBI_free_result($tab_rs);
  139.     } else {
  140.         $cfg['Server']['pmadb'] = false;
  141.     }
  142.  
  143.     if (isset($cfgRelation['relation'])) {
  144.         $cfgRelation['relwork']         = true;
  145.         if (isset($cfgRelation['table_info'])) {
  146.                 $cfgRelation['displaywork'] = true;
  147.         }
  148.     }
  149.     if (isset($cfgRelation['table_coords']) && isset($cfgRelation['pdf_pages'])) {
  150.         $cfgRelation['pdfwork']     = true;
  151.     }
  152.     if (isset($cfgRelation['column_info'])) {
  153.         $cfgRelation['commwork']    = true;
  154.  
  155.         if ($cfg['Server']['verbose_check']) {
  156.             $mime_query  = 'SHOW FIELDS FROM '
  157.                 . PMA_backquote($cfgRelation['db']) . '.'
  158.                 . PMA_backquote($cfgRelation['column_info']);
  159.             $mime_rs     = PMA_query_as_cu($mime_query, false);
  160.  
  161.             $mime_field_mimetype                = false;
  162.             $mime_field_transformation          = false;
  163.             $mime_field_transformation_options  = false;
  164.             while ($curr_mime_field = @PMA_DBI_fetch_row($mime_rs)) {
  165.                 if ($curr_mime_field[0] == 'mimetype') {
  166.                     $mime_field_mimetype               = true;
  167.                 } elseif ($curr_mime_field[0] == 'transformation') {
  168.                     $mime_field_transformation         = true;
  169.                 } elseif ($curr_mime_field[0] == 'transformation_options') {
  170.                     $mime_field_transformation_options = true;
  171.                 }
  172.             }
  173.             PMA_DBI_free_result($mime_rs);
  174.  
  175.             if ($mime_field_mimetype == true
  176.                 && $mime_field_transformation == true
  177.                 && $mime_field_transformation_options == true) {
  178.                 $cfgRelation['mimework'] = true;
  179.             }
  180.         } else {
  181.             $cfgRelation['mimework'] = true;
  182.         }
  183.     }
  184.  
  185.     if (isset($cfgRelation['history'])) {
  186.         $cfgRelation['historywork']     = true;
  187.     }
  188.  
  189.     if (isset($cfgRelation['bookmark'])) {
  190.         $cfgRelation['bookmarkwork']     = true;
  191.     }
  192.  
  193.     if ($cfgRelation['relwork'] == true && $cfgRelation['displaywork'] == true
  194.         && $cfgRelation['pdfwork'] == true && $cfgRelation['commwork'] == true
  195.         && $cfgRelation['mimework'] == true && $cfgRelation['historywork'] == true
  196.         && $cfgRelation['bookmarkwork'] == true) {
  197.         $cfgRelation['allworks'] = true;
  198.     }
  199.  
  200.     if ($verbose == true) {
  201.         $shit     = '<font color="red"><b>' . $GLOBALS['strNotOK']
  202.             . '</b></font> [ <a href="Documentation.html#%s">'
  203.             . $GLOBALS['strDocu'] . '</a> ]';
  204.         $hit      = '<font color="green"><b>' . $GLOBALS['strOK'] . '</b></font>';
  205.         $enabled  = '<font color="green">' . $GLOBALS['strEnabled'] . '</font>';
  206.         $disabled = '<font color="red">'   . $GLOBALS['strDisabled'] . '</font>';
  207.  
  208.         echo '<table>' . "\n";
  209.         echo '    <tr><th align="left">$cfg[\'Servers\'][$i][\'pmadb\'] ... </th><td align="right">'
  210.              . (($cfg['Server']['pmadb'] == false) ? sprintf($shit, 'pmadb') : $hit)
  211.              . '</td></tr>' . "\n";
  212.         echo '    <tr><td> </td></tr>' . "\n";
  213.  
  214.         echo '    <tr><th align="left">$cfg[\'Servers\'][$i][\'relation\'] ... </th><td align="right">'
  215.              . ((isset($cfgRelation['relation'])) ? $hit : sprintf($shit, 'relation'))
  216.              . '</td></tr>' . "\n";
  217.         echo '    <tr><td colspan=2 align="center">'. $GLOBALS['strGeneralRelationFeat'] . ': '
  218.              . (($cfgRelation['relwork'] == true) ? $enabled :  $disabled)
  219.              . '</td></tr>' . "\n";
  220.         echo '    <tr><td> </td></tr>' . "\n";
  221.  
  222.         echo '    <tr><th align="left">$cfg[\'Servers\'][$i][\'table_info\']   ... </th><td align="right">'
  223.              . (($cfgRelation['displaywork'] == false) ? sprintf($shit, 'table_info') : $hit)
  224.              . '</td></tr>' . "\n";
  225.         echo '    <tr><td colspan=2 align="center">' . $GLOBALS['strDisplayFeat'] . ': '
  226.              . (($cfgRelation['displaywork'] == true) ? $enabled : $disabled)
  227.              . '</td></tr>' . "\n";
  228.         echo '    <tr><td> </td></tr>' . "\n";
  229.  
  230.         echo '    <tr><th align="left">$cfg[\'Servers\'][$i][\'table_coords\'] ... </th><td align="right">'
  231.              . ((isset($cfgRelation['table_coords'])) ? $hit : sprintf($shit, 'table_coords'))
  232.              . '</td></tr>' . "\n";
  233.         echo '    <tr><th align="left">$cfg[\'Servers\'][$i][\'pdf_pages\'] ... </th><td align="right">'
  234.              . ((isset($cfgRelation['pdf_pages'])) ? $hit : sprintf($shit, 'table_coords'))
  235.              . '</td></tr>' . "\n";
  236.         echo '    <tr><td colspan=2 align="center">' . $GLOBALS['strCreatePdfFeat'] . ': '
  237.              . (($cfgRelation['pdfwork'] == true) ? $enabled : $disabled)
  238.              . '</td></tr>' . "\n";
  239.         echo '    <tr><td> </td></tr>' . "\n";
  240.  
  241.         echo '    <tr><th align="left">$cfg[\'Servers\'][$i][\'column_info\'] ... </th><td align="right">'
  242.              . ((isset($cfgRelation['column_info'])) ? $hit : sprintf($shit, 'col_com'))
  243.              . '</td></tr>' . "\n";
  244.         echo '    <tr><td colspan=2 align="center">' . $GLOBALS['strColComFeat'] . ': '
  245.              . (($cfgRelation['commwork'] == true) ? $enabled : $disabled)
  246.              . '</td></tr>' . "\n";
  247.         echo '    <tr><td colspan=2 align="center">' . $GLOBALS['strBookmarkQuery'] . ': '
  248.              . (($cfgRelation['bookmarkwork'] == true) ? $enabled : $disabled)
  249.              . '</td></tr>' . "\n";
  250.         echo '    <tr><th align="left">MIME ...</th><td align="right">'
  251.              . (($cfgRelation['mimework'] == true) ? $hit : sprintf($shit, 'col_com'))
  252.              . '</td></tr>' . "\n";
  253.  
  254.              if (($cfgRelation['commwork'] == true) && ($cfgRelation['mimework'] != true)) {
  255.                  echo '<tr><td colspan=2 align="left">' . $GLOBALS['strUpdComTab'] . '</td></tr>' . "\n";
  256.              }
  257.  
  258.         echo '    <tr><th align="left">$cfg[\'Servers\'][$i][\'history\'] ... </th><td align="right">'
  259.              . ((isset($cfgRelation['history'])) ? $hit : sprintf($shit, 'history'))
  260.              . '</td></tr>' . "\n";
  261.         echo '    <tr><td colspan=2 align="center">' . $GLOBALS['strQuerySQLHistory'] . ': '
  262.              . (($cfgRelation['historywork'] == true) ? $enabled : $disabled)
  263.              . '</td></tr>' . "\n";
  264.  
  265.         echo '</table>' . "\n";
  266.     } // end if ($verbose == true) {
  267.  
  268.     return $cfgRelation;
  269. } // end of the 'PMA_getRelationsParam()' function
  270.  
  271.  
  272. /**
  273.  * Gets all Relations to foreign tables for a given table or
  274.  * optionally a given column in a table
  275.  *
  276.  * @param   string   the name of the db to check for
  277.  * @param   string   the name of the table to check for
  278.  * @param   string   the name of the column to check for
  279.  * @param   string   the source for foreign key information
  280.  *
  281.  * @return  array    db,table,column
  282.  *
  283.  * @global  array    the list of relations settings
  284.  * @global  string   the URL of the page to show in case of error
  285.  *
  286.  * @access  public
  287.  *
  288.  * @author  Mike Beck <mikebeck@users.sourceforge.net> and Marc Delisle
  289.  */
  290. function PMA_getForeigners($db, $table, $column = '', $source = 'both') {
  291.     global $cfgRelation;
  292.  
  293.     if ($cfgRelation['relwork'] && ($source == 'both' || $source == 'internal')) {
  294.         $rel_query = '
  295.              SELECT master_field,
  296.                     foreign_db,
  297.                     foreign_table,
  298.                     foreign_field
  299.                FROM ' . PMA_backquote($cfgRelation['db']) . '.' . PMA_backquote($cfgRelation['relation']) . '
  300.               WHERE master_db =  \'' . PMA_sqlAddslashes($db) . '\'
  301.                 AND master_table = \'' . PMA_sqlAddslashes($table) . '\' ';
  302.         if (isset($column) && strlen($column)) {
  303.             $rel_query .= ' AND   master_field = \'' . PMA_sqlAddslashes($column) . '\'';
  304.         }
  305.         $relations     = PMA_query_as_cu($rel_query);
  306.         $i = 0;
  307.         while ($relrow = PMA_DBI_fetch_assoc($relations)) {
  308.             $field                            = $relrow['master_field'];
  309.             $foreign[$field]['foreign_db']    = $relrow['foreign_db'];
  310.             $foreign[$field]['foreign_table'] = $relrow['foreign_table'];
  311.             $foreign[$field]['foreign_field'] = $relrow['foreign_field'];
  312.             $i++;
  313.         } // end while
  314.         PMA_DBI_free_result($relations);
  315.         unset($relations);
  316.     }
  317.  
  318.     if (($source == 'both' || $source == 'innodb') && isset($table) && strlen($table)) {
  319.         $show_create_table_query = 'SHOW CREATE TABLE '
  320.             . PMA_backquote($db) . '.' . PMA_backquote($table);
  321.         $show_create_table_res = PMA_DBI_query($show_create_table_query);
  322.         list(, $show_create_table) = PMA_DBI_fetch_row($show_create_table_res);
  323.         PMA_DBI_free_result($show_create_table_res);
  324.         unset($show_create_table_res, $show_create_table_query);
  325.         $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($show_create_table));
  326.  
  327.         foreach ($analyzed_sql[0]['foreign_keys'] AS $one_key) {
  328.  
  329.         // the analyzer may return more than one column name in the
  330.         // index list or the ref_index_list
  331.             foreach ($one_key['index_list'] AS $i => $field) {
  332.  
  333.         // If a foreign key is defined in the 'internal' source (pmadb)
  334.         // and in 'innodb', we won't get it twice if $source='both'
  335.         // because we use $field as key
  336.  
  337.                 // The parser looks for a CONSTRAINT clause just before
  338.                 // the FOREIGN KEY clause. It finds it (as output from
  339.                 // SHOW CREATE TABLE) in MySQL 4.0.13, but not in older
  340.                 // versions like 3.23.58.
  341.                 // In those cases, the FOREIGN KEY parsing will put numbers
  342.                 // like -1, 0, 1... instead of the constraint number.
  343.  
  344.                 if (isset($one_key['constraint'])) {
  345.                     $foreign[$field]['constraint'] = $one_key['constraint'];
  346.                 }
  347.  
  348.                 if (isset($one_key['ref_db_name'])) {
  349.                     $foreign[$field]['foreign_db']    = $one_key['ref_db_name'];
  350.                 } else {
  351.                     $foreign[$field]['foreign_db']    = $db;
  352.                 }
  353.                 $foreign[$field]['foreign_table'] = $one_key['ref_table_name'];
  354.                 $foreign[$field]['foreign_field'] = $one_key['ref_index_list'][$i];
  355.                 if (isset($one_key['on_delete'])) {
  356.                     $foreign[$field]['on_delete'] = $one_key['on_delete'];
  357.                 }
  358.                 if (isset($one_key['on_update'])) {
  359.                     $foreign[$field]['on_update'] = $one_key['on_update'];
  360.                 }
  361.             }
  362.         }
  363.     }
  364.  
  365.     /**
  366.      * Emulating relations for some information_schema tables
  367.      */
  368.     if (PMA_MYSQL_INT_VERSION >= 50002 && $db == 'information_schema'
  369.         && ($source == 'internal' || $source == 'both')) {
  370.  
  371.         require_once './libraries/information_schema_relations.lib.php';
  372.  
  373.         if (!isset($foreign)) {
  374.             $foreign = array();
  375.         }
  376.  
  377.         if (isset($GLOBALS['information_schema_relations'][$table])) {
  378.             foreach ($GLOBALS['information_schema_relations'][$table] as $field => $relations) {
  379.                 if ((! isset($column) || ! strlen($column) || $column == $field)
  380.                   && (! isset($foreign[$field]) || ! strlen($foreign[$field]))) {
  381.                     $foreign[$field] = $relations;
  382.                 }
  383.             }
  384.         }
  385.     }
  386.  
  387.     if (!empty($foreign) && is_array($foreign)) {
  388.        return $foreign;
  389.     } else {
  390.         return false;
  391.     }
  392.  
  393. } // end of the 'PMA_getForeigners()' function
  394.  
  395.  
  396. /**
  397.  * Gets the display field of a table
  398.  *
  399.  * @param   string   the name of the db to check for
  400.  * @param   string   the name of the table to check for
  401.  *
  402.  * @return  string   field name
  403.  *
  404.  * @global  array    the list of relations settings
  405.  *
  406.  * @access  public
  407.  *
  408.  * @author  Mike Beck <mikebeck@users.sourceforge.net>
  409.  */
  410. function PMA_getDisplayField($db, $table) {
  411.     global $cfgRelation;
  412.  
  413.     /**
  414.      * Try to fetch the display field from DB.
  415.      */
  416.     if (trim(@$cfgRelation['table_info']) != '') {
  417.  
  418.         $disp_query = '
  419.              SELECT display_field
  420.                FROM ' . PMA_backquote($cfgRelation['db']) . '.' . PMA_backquote($cfgRelation['table_info']) . '
  421.               WHERE db_name    = \'' . PMA_sqlAddslashes($db) . '\'
  422.                 AND table_name = \'' . PMA_sqlAddslashes($table) . '\'';
  423.  
  424.         $disp_res   = PMA_query_as_cu($disp_query);
  425.         $row        = ($disp_res ? PMA_DBI_fetch_assoc($disp_res) : '');
  426.         PMA_DBI_free_result($disp_res);
  427.         if (isset($row['display_field'])) {
  428.             return $row['display_field'];
  429.         }
  430.  
  431.     }
  432.  
  433.     /**
  434.      * Emulating the display field for some information_schema tables.
  435.      */
  436.     if (PMA_MYSQL_INT_VERSION >= 50002 && $db == 'information_schema') {
  437.         switch ($table) {
  438.             case 'CHARACTER_SETS': return 'DESCRIPTION';
  439.             case 'TABLES':         return 'TABLE_COMMENT';
  440.         }
  441.     }
  442.  
  443.     /**
  444.      * No Luck...
  445.      */
  446.     return false;
  447.  
  448. } // end of the 'PMA_getDisplayField()' function
  449.  
  450.  
  451. /**
  452.  * Gets the comments for all rows of a table
  453.  *
  454.  * @param   string   the name of the db to check for
  455.  * @param   string   the name of the table to check for
  456.  *
  457.  * @return  array    [field_name] = comment
  458.  *
  459.  * @global  array    the list of relations settings
  460.  *
  461.  * @access  public
  462.  *
  463.  * @authors  Mike Beck <mikebeck@users.sourceforge.net>
  464.  *           and lem9
  465.  */
  466. function PMA_getComments($db, $table = '') {
  467.     global $cfgRelation;
  468.  
  469.     if ($table != '') {
  470.  
  471.         // MySQL 4.1.x native column comments
  472.         if (PMA_MYSQL_INT_VERSION >= 40100) {
  473.             $fields = PMA_DBI_get_fields($db, $table);
  474.             if ($fields) {
  475.                 foreach ($fields as $key=>$field) {
  476.                     $tmp_col = $field['Field'];
  477.                     if (!empty($field['Comment'])) {
  478.                         $native_comment[$tmp_col] = $field['Comment'];
  479.                     }
  480.                 }
  481.                 if (isset($native_comment)) {
  482.                     $comment = $native_comment;
  483.                 }
  484.             }
  485.         }
  486.  
  487.         // pmadb internal column comments
  488.         // (this function can be called even if $cfgRelation['commwork'] is
  489.         // false, to get native column comments, so recheck here)
  490.         if ($cfgRelation['commwork']) {
  491.             $com_qry = '
  492.                  SELECT column_name,
  493.                         comment
  494.                    FROM ' . PMA_backquote($cfgRelation['db']) . '.' .PMA_backquote($cfgRelation['column_info']) . '
  495.                   WHERE db_name    = \'' . PMA_sqlAddslashes($db) . '\'
  496.                     AND table_name = \'' . PMA_sqlAddslashes($table) . '\'';
  497.             $com_rs   = PMA_query_as_cu($com_qry, true, PMA_DBI_QUERY_STORE);
  498.         }
  499.     } else {
  500.         // pmadb internal db comments
  501.         $com_qry = '
  502.              SELECT ' . PMA_backquote('comment') . '
  503.                FROM ' . PMA_backquote($cfgRelation['db']) . '.' . PMA_backquote($cfgRelation['column_info']) . '
  504.               WHERE db_name     = \'' . PMA_sqlAddslashes($db) . '\'
  505.                 AND table_name  = \'\'
  506.                 AND column_name = \'(db_comment)\'';
  507.         $com_rs   = PMA_query_as_cu($com_qry, true, PMA_DBI_QUERY_STORE);
  508.     }
  509.  
  510.  
  511.     if (isset($com_rs) && PMA_DBI_num_rows($com_rs) > 0) {
  512.         $i = 0;
  513.         while ($row = PMA_DBI_fetch_assoc($com_rs)) {
  514.             $i++;
  515.             $col           = ($table != '' ? $row['column_name'] : $i);
  516.  
  517.             if (strlen($row['comment']) > 0) {
  518.                 $comment[$col] = $row['comment'];
  519.                 // if this version supports native comments and this function
  520.                 // was called with a table parameter
  521.                 if (PMA_MYSQL_INT_VERSION >= 40100 && isset($table) && strlen($table)) {
  522.                     // if native comment found, use it instead of pmadb
  523.                     if (!empty($native_comment[$col])) {
  524.                         $comment[$col] = $native_comment[$col];
  525.                     } else {
  526.                         // no native comment, so migrate pmadb-style to native
  527.                         PMA_setComment($db, $table, $col, $comment[$col], '', 'native');
  528.                         // and erase the pmadb-style comment
  529.                         PMA_setComment($db, $table, $col, '', '', 'pmadb');
  530.                     }
  531.                 }
  532.             }
  533.         } // end while
  534.  
  535.         PMA_DBI_free_result($com_rs);
  536.         unset($com_rs);
  537.     }
  538.  
  539.     if (isset($comment) && is_array($comment)) {
  540.         return $comment;
  541.      } else {
  542.         return false;
  543.      }
  544.  } // end of the 'PMA_getComments()' function
  545.  
  546. /**
  547.  * Adds/removes slashes if required
  548.  *
  549.  * @param   string  the string to slash
  550.  *
  551.  * @return  string  the slashed string
  552.  *
  553.  * @access  public
  554.  */
  555. function PMA_handleSlashes($val) {
  556.   return PMA_sqlAddslashes($val);
  557. } // end of the "PMA_handleSlashes()" function
  558.  
  559. /**
  560.  * Set a single comment to a certain value.
  561.  *
  562.  * @param   string   the name of the db
  563.  * @param   string   the name of the table (may be empty in case of a db comment)
  564.  * @param   string   the name of the column
  565.  * @param   string   the value of the column
  566.  * @param   string   (optional) if a column is renamed, this is the name of the former key which will get deleted
  567.  * @param   string   whether we set pmadb comments, native comments or both
  568.  *
  569.  * @return  boolean  true, if comment-query was made.
  570.  *
  571.  * @global  array    the list of relations settings
  572.  *
  573.  * @access  public
  574.  */
  575. function PMA_setComment($db, $table, $col, $comment, $removekey = '', $mode='auto') {
  576.     global $cfgRelation;
  577.  
  578.     if ($mode=='auto') {
  579.         if (PMA_MYSQL_INT_VERSION >= 40100) {
  580.             $mode='native';
  581.         } else {
  582.             $mode='pmadb';
  583.         }
  584.     }
  585.  
  586.     // native mode is only for column comments so we need a table name
  587.     if ($mode == 'native' && isset($table) && strlen($table)) {
  588.         $query = 'ALTER TABLE ' . PMA_backquote($table) . ' CHANGE '
  589.             . PMA_Table::generateAlter($col, $col, '', '', '', '', false, '', false, '', $comment, '', '');
  590.         PMA_DBI_try_query($query, null, PMA_DBI_QUERY_STORE);
  591.         return true;
  592.     }
  593.  
  594.     // $mode == 'pmadb' section:
  595.  
  596.     $cols = array(
  597.         'db_name'     => 'db_name    ',
  598.         'table_name'  => 'table_name ',
  599.         'column_name' => 'column_name'
  600.     );
  601.  
  602.     if ($removekey != '' AND $removekey != $col) {
  603.         $remove_query = '
  604.              DELETE FROM
  605.                     ' . PMA_backquote($cfgRelation['db']) . '.' . PMA_backquote($cfgRelation['column_info']) . '
  606.               WHERE ' . $cols['db_name']     . ' = \'' . PMA_sqlAddslashes($db) . '\'
  607.                 AND ' . $cols['table_name']  . ' = \'' . PMA_sqlAddslashes($table) . '\'
  608.                 AND ' . $cols['column_name'] . ' = \'' . PMA_sqlAddslashes($removekey) . '\'';
  609.         PMA_query_as_cu($remove_query);
  610.         unset($remove_query);
  611.     }
  612.  
  613.     $test_qry = '
  614.          SELECT ' . PMA_backquote('comment') . ',
  615.                 mimetype,
  616.                 transformation,
  617.                 transformation_options
  618.            FROM ' . PMA_backquote($cfgRelation['db']) . '.' . PMA_backquote($cfgRelation['column_info']) . '
  619.           WHERE ' . $cols['db_name']     . ' = \'' . PMA_sqlAddslashes($db) . '\'
  620.             AND ' . $cols['table_name']  . ' = \'' . PMA_sqlAddslashes($table) . '\'
  621.             AND ' . $cols['column_name'] . ' = \'' . PMA_sqlAddslashes($col) . '\'';
  622.     $test_rs   = PMA_query_as_cu($test_qry, true, PMA_DBI_QUERY_STORE);
  623.  
  624.     if ($test_rs && PMA_DBI_num_rows($test_rs) > 0) {
  625.         $row = PMA_DBI_fetch_assoc($test_rs);
  626.         PMA_DBI_free_result($test_rs);
  627.  
  628.         if (strlen($comment) > 0 || strlen($row['mimetype']) > 0 || strlen($row['transformation']) > 0 || strlen($row['transformation_options']) > 0) {
  629.             $upd_query = '
  630.                  UPDATE ' . PMA_backquote($cfgRelation['db']) . '.' . PMA_backquote($cfgRelation['column_info']) . '
  631.                     SET ' . PMA_backquote('comment') . ' = \'' . PMA_sqlAddslashes($comment) . '\'
  632.                   WHERE ' . $cols['db_name']     . ' = \'' . PMA_sqlAddslashes($db) . '\'
  633.                     AND ' . $cols['table_name']  . ' = \'' . PMA_sqlAddslashes($table) . '\'
  634.                     AND ' . $cols['column_name'] . ' = \'' . PMA_sqlAddSlashes($col) . '\'';
  635.         } else {
  636.             $upd_query = '
  637.                  DELETE FROM
  638.                         ' . PMA_backquote($cfgRelation['db']) . '.' . PMA_backquote($cfgRelation['column_info']) . '
  639.                   WHERE ' . $cols['db_name']     . ' = \'' . PMA_sqlAddslashes($db) . '\'
  640.                     AND ' . $cols['table_name']  . ' = \'' . PMA_sqlAddslashes($table) . '\'
  641.                     AND ' . $cols['column_name'] . ' = \'' . PMA_sqlAddslashes($col) . '\'';
  642.         }
  643.     } elseif (strlen($comment) > 0) {
  644.         $upd_query = '
  645.              INSERT INTO
  646.                     ' . PMA_backquote($cfgRelation['db']) . '.' . PMA_backquote($cfgRelation['column_info']) . '
  647.                     (db_name, table_name, column_name, ' . PMA_backquote('comment') . ')
  648.              VALUES (
  649.                    \'' . PMA_sqlAddslashes($db) . '\',
  650.                    \'' . PMA_sqlAddslashes($table) . '\',
  651.                    \'' . PMA_sqlAddslashes($col) . '\',
  652.                    \'' . PMA_sqlAddslashes($comment) . '\')';
  653.     }
  654.  
  655.     if (isset($upd_query)){
  656.         $upd_rs    = PMA_query_as_cu($upd_query);
  657.         unset($upd_query);
  658.         return true;
  659.     } else {
  660.         return false;
  661.     }
  662. } // end of 'PMA_setComment()' function
  663.  
  664. /**
  665.  * Set a SQL history entry
  666.  *
  667.  * @param   string   the name of the db
  668.  * @param   string   the name of the table
  669.  * @param   string   the username
  670.  * @param   string   the sql query
  671.  *
  672.  * @global  array    the list of relations settings
  673.  *
  674.  * @return  boolean  true
  675.  *
  676.  * @access  public
  677.  */
  678. function PMA_setHistory($db, $table, $username, $sqlquery) {
  679.     global $cfgRelation;
  680.  
  681.     $hist_rs = PMA_query_as_cu('
  682.          INSERT INTO
  683.                 ' . PMA_backquote($cfgRelation['db']) . '.' . PMA_backquote($cfgRelation['history']) . '
  684.               (' . PMA_backquote('username') . ',
  685.                 ' . PMA_backquote('db') . ',
  686.                 ' . PMA_backquote('table') . ',
  687.                 ' . PMA_backquote('timevalue') . ',
  688.                 ' . PMA_backquote('sqlquery') . ')
  689.          VALUES
  690.               (\'' . PMA_sqlAddslashes($username) . '\',
  691.                 \'' . PMA_sqlAddslashes($db) . '\',
  692.                 \'' . PMA_sqlAddslashes($table) . '\',
  693.                 NOW(),
  694.                 \'' . PMA_sqlAddslashes($sqlquery) . '\')');
  695.     return true;
  696. } // end of 'PMA_setHistory()' function
  697.  
  698. /**
  699.  * Gets a SQL history entry
  700.  *
  701.  * @param   string   the username
  702.  *
  703.  * @global  array    the list of relations settings
  704.  *
  705.  * @return  array    list of history items
  706.  *
  707.  * @access  public
  708.  */
  709. function PMA_getHistory($username) {
  710.     global $cfgRelation;
  711.  
  712.     $hist_query = '
  713.          SELECT ' . PMA_backquote('db') . ',
  714.                 ' . PMA_backquote('table') . ',
  715.                 ' . PMA_backquote('sqlquery') . '
  716.            FROM ' . PMA_backquote($cfgRelation['db']) . '.' . PMA_backquote($cfgRelation['history']) . '
  717.           WHERE username = \'' . PMA_sqlAddslashes($username) . '\'
  718.        ORDER BY id DESC';
  719.  
  720.     $hist_rs = PMA_query_as_cu($hist_query);
  721.     unset($hist_query);
  722.  
  723.     $history = array();
  724.  
  725.     while ($row = PMA_DBI_fetch_assoc($hist_rs)) {
  726.         $history[] = $row;
  727.     }
  728.     PMA_DBI_free_result($hist_rs);
  729.  
  730.     return $history;
  731.  
  732. } // end of 'PMA_getHistory()' function
  733.  
  734. /**
  735.  * Set a SQL history entry
  736.  *
  737.  * @param   string   the name of the db
  738.  * @param   string   the name of the table
  739.  * @param   string   the username
  740.  * @param   string   the sql query
  741.  *
  742.  * @global  array    the list of relations settings
  743.  * @global  array    global phpMyAdmin configuration
  744.  *
  745.  * @return  boolean  true
  746.  *
  747.  * @access  public
  748.  */
  749. function PMA_purgeHistory($username) {
  750.     global $cfgRelation, $cfg;
  751.  
  752.     $purge_query = '
  753.          SELECT timevalue
  754.            FROM ' . PMA_backquote($cfgRelation['db']) . '.' . PMA_backquote($cfgRelation['history']) . '
  755.           WHERE username = \'' . PMA_sqlAddSlashes($username) . '\'
  756.        ORDER BY timevalue DESC LIMIT ' . $cfg['QueryHistoryMax'] . ', 1';
  757.     $purge_rs = PMA_query_as_cu($purge_query);
  758.     $i = 0;
  759.     $row = PMA_DBI_fetch_row($purge_rs);
  760.     PMA_DBI_free_result($purge_rs);
  761.  
  762.     if (is_array($row) && isset($row[0]) && $row[0] > 0) {
  763.         $maxtime = $row[0];
  764.         // quotes added around $maxtime to prevent a difficult to
  765.         // reproduce problem
  766.         $remove_rs = PMA_query_as_cu('
  767.              DELETE FROM
  768.                     ' . PMA_backquote($cfgRelation['db']) . '.' . PMA_backquote($cfgRelation['history']) . '
  769.               WHERE timevalue <= \'' . $maxtime . '\'');
  770.     }
  771.  
  772.     return true;
  773. } // end of 'PMA_purgeHistory()' function
  774.  
  775.  
  776. /**
  777.  * Prepares the dropdown for one mode
  778.  *
  779.  * @param   array    the keys and values for foreigns
  780.  * @param   string   the current data of the dropdown
  781.  * @param   string   the needed mode
  782.  *
  783.  * @global  array    global phpMyAdmin configuration
  784.  *
  785.  * @return  array   the <option value=""><option>s
  786.  *
  787.  * @access  private
  788.  */
  789. function PMA_foreignDropdownBuild($foreign, $data, $mode) {
  790.     global $cfg;
  791.  
  792.     $reloptions = array();
  793.  
  794.     foreach ($foreign as $key => $value) {
  795.  
  796.         if (PMA_strlen($value) <= $cfg['LimitChars']) {
  797.             $vtitle = '';
  798.             $value  = htmlspecialchars($value);
  799.         } else {
  800.             $vtitle  = htmlspecialchars($value);
  801.             $value  = htmlspecialchars(substr($value, 0, $cfg['LimitChars']) . '...');
  802.         }
  803.  
  804.         $reloption = '                <option value="' . htmlspecialchars($key) . '"';
  805.         if ($vtitle != '') {
  806.             $reloption .= ' title="' . $vtitle . '"';
  807.         }
  808.  
  809.         if ((string) $key == (string) $data) {
  810.            $reloption .= ' selected="selected"';
  811.         }
  812.  
  813.         if ($mode == 'content-id') {
  814.             $reloptions[] = $reloption . '>' . $value . ' - ' . htmlspecialchars($key) .  '</option>' . "\n";
  815.         } else {
  816.             $reloptions[] = $reloption . '>' . htmlspecialchars($key) .  ' - ' . $value . '</option>' . "\n";
  817.         }
  818.     } // end foreach
  819.  
  820.     return $reloptions;
  821. } // end of 'PMA_foreignDropdownBuild' function
  822.  
  823. /**
  824.  * Outputs dropdown with values of foreign fields
  825.  *
  826.  * @param   string   the query of the foreign keys
  827.  * @param   string   the foreign field
  828.  * @param   string   the foreign field to display
  829.  * @param   string   the current data of the dropdown
  830.  *
  831.  * @global  array    global phpMyAdmin configuration
  832.  *
  833.  * @return  string   the <option value=""><option>s
  834.  *
  835.  * @access  public
  836.  */
  837. function PMA_foreignDropdown($disp, $foreign_field, $foreign_display, $data, $max) {
  838.     global $cfg;
  839.  
  840.     $foreign = array();
  841.  
  842.     // collect the data
  843.     foreach ($disp as $relrow) {
  844.         $key   = $relrow[$foreign_field];
  845.  
  846.         // if the display field has been defined for this foreign table
  847.         if ($foreign_display) {
  848.             $value  = $relrow[$foreign_display];
  849.         } else {
  850.             $value = '';
  851.         } // end if ($foreign_display)
  852.  
  853.         $foreign[$key] = $value;
  854.     } // end foreach
  855.  
  856.     // beginning of dropdown
  857.     $ret = '<option value=""></option>' . "\n";
  858.  
  859.     // master array for dropdowns
  860.     $reloptions = array('content-id' => array(), 'id-content' => array());
  861.  
  862.     // sort for id-content
  863.     if ($cfg['NaturalOrder']) {
  864.         uksort($foreign, 'strnatcasecmp');
  865.     } else {
  866.         ksort($foreign);
  867.     }
  868.  
  869.     // build id-content dropdown
  870.     $reloptions['id-content'] = PMA_foreignDropdownBuild($foreign, $data, 'id-content');
  871.  
  872.     // sort for content-id
  873.     if ($cfg['NaturalOrder']) {
  874.         natcasesort($foreign);
  875.     } else {
  876.         asort($foreign);
  877.     }
  878.  
  879.     // build content-id dropdown
  880.     $reloptions['content-id'] = PMA_foreignDropdownBuild($foreign, $data, 'content-id');
  881.  
  882.  
  883.     // put the dropdown sections in correct order
  884.  
  885.     $c = count($cfg['ForeignKeyDropdownOrder']);
  886.     if ($c == 2) {
  887.         $top = $reloptions[$cfg['ForeignKeyDropdownOrder'][0]];
  888.         $bot = $reloptions[$cfg['ForeignKeyDropdownOrder'][1]];
  889.     } elseif ($c == 1) {
  890.         $bot = $reloptions[$cfg['ForeignKeyDropdownOrder'][0]];
  891.         $top = null;
  892.     } else {
  893.         $top = $reloptions['id-content'];
  894.         $bot = $reloptions['content-id'];
  895.     }
  896.     $str_bot = implode('', $bot);
  897.     if ($top !== null) {
  898.         $str_top = implode('', $top);
  899.         $top_count = count($top);
  900.         if ($max == -1 || $top_count < $max) {
  901.             $ret .= $str_top;
  902.             if ($top_count > 0) {
  903.                 $ret .= '                <option value=""></option>' . "\n";
  904.                 $ret .= '                <option value=""></option>' . "\n";
  905.             }
  906.         }
  907.     }
  908.     $ret .= $str_bot;
  909.  
  910.     return $ret;
  911. } // end of 'PMA_foreignDropdown()' function
  912.  
  913. ?>
  914.